package cn.com.cfae.iras.doc.analyze.components;

import cn.com.cfae.iras.doc.analyze.beans.iaad.IaadGrade;
import cn.com.cfae.iras.doc.analyze.beans.iaad.IaadIndicatorGradeDetail;
import cn.com.cfae.iras.doc.analyze.beans.iaad.IndustryIndicatorList;
import cn.com.cfae.iras.doc.analyze.beans.iaad.IndustryIndicatorThreshold;
import cn.com.cfae.iras.doc.analyze.beans.web.ContentAndPosition;
import cn.com.cfae.iras.doc.analyze.components.beans.ComponentResult;
import cn.com.cfae.iras.doc.analyze.parse.GsonUtil;
import cn.com.cfae.iras.doc.analyze.parse.kv.KVText;
import cn.com.cfae.iras.doc.analyze.parse.kv.TextLayout;
import cn.com.cfae.iras.doc.analyze.parse.model.*;
import cn.com.cfae.iras.doc.analyze.pdf.PdfExtractor;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;

import java.sql.Timestamp;
import java.text.DecimalFormat;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by 佟媛媛 on 18/10/24.
 */
public abstract class BaseComponent extends BaseCommon {

    private static Logger log = LoggerFactory.getLogger(BaseComponent.class);

    /**
     * @auth 佟媛媛
     * @date 18/10/24 下午4:54
     * @desc 处理规则 M
     */
    public abstract List<ComponentResult> handlerM();

    /**
     * @auth 佟媛媛
     * @date 18/10/24 下午4:54
     * @desc 处理规则 BM
     */
    public abstract List<ComponentResult> handlerBM();

    /**
     * @auth 佟媛媛
     * @date 18/10/24 下午4:54
     * @desc 处理规则 DM
     */
    public abstract List<ComponentResult> handlerDM();

    /**
     * @auth 佟媛媛
     * @date 18/10/24 下午4:54
     * @desc 处理规则 DBM
     */
    public abstract List<ComponentResult> handlerBDM();

    private DocumentModel extractData;//分析后数据
    private String stage;// 发行阶段。"01"预评阶段，"02"发行阶段
    private String options;//更多选项。"1001" 是否涉及投资人保护条款，"1002" 是否引用20xx年第xx期xx品种募集说明书 ;
    private String regulationId;//规则ID
    private String ruleTitle;//规则名
    private String catalogId;//目录ID
    private String chapterId;//章节ID
    private List<IndustryIndicatorList> industryIndicatorList;//指标
    private IaadGrade iaadGrade;//评分
    private String promptMsg;//提示信息


    public DocumentModel getExtractData() {
        return extractData;
    }

    public void setExtractData(DocumentModel extractData) {
        this.extractData = extractData;
    }


    public String getStage() {
        return stage;
    }

    public void setStage(String stage) {
        this.stage = stage;
    }

    public String getOptions() {
        return options;
    }

    public void setOptions(String options) {
        this.options = options;
    }

    public String getRegulationId() {
        return regulationId;
    }

    public void setRegulationId(String regulationId) {
        this.regulationId = regulationId;
    }

    public String getRuleTitle() {
        return ruleTitle;
    }

    public void setRuleTitle(String ruleTitle) {
        this.ruleTitle = ruleTitle;
    }

    public String getCatalogId() {
        return catalogId;
    }

    public void setCatalogId(String catalogId) {
        this.catalogId = catalogId;
    }

    public String getChapterId() {
        return chapterId;
    }

    public void setChapterId(String chapterId) {
        this.chapterId = chapterId;
    }

    public ChapterModel getChapterModel(String tableId) {
        DocumentModel extractData = getExtractData();//抽取文本
        if (extractData == null) return new ChapterModel();
        ChapterModel chapterModel = extractData.getChapterModel(tableId);
        return chapterModel == null ? new ChapterModel() : chapterModel;
    }

    public PageModel getPageModel(String tableId, int pageNum) {
        List<PageModel> pageModelList = getChapterModel(tableId).getPageModelList();
        if (org.apache.commons.collections.CollectionUtils.isNotEmpty(pageModelList)) {
            for (PageModel pageModel : pageModelList) {
                if (pageNum == pageModel.getPageNumber()) {
                    return pageModel;
                }
            }
        }
        return new PageModel();
    }

    public ExtractBizModel getModel(String tableId, String model) {
        ExtractBizModel extractBizModel = getChapterModel(tableId).getModel(model);
        return extractBizModel == null ? new ExtractBizModel() : extractBizModel;
    }

    public KVText getKVTextKey(String tableId, String model, String key) {
        ExtractBizModel extractBizModel = getChapterModel(tableId).getModel(model);
        if (extractBizModel != null) {
            ExtractItem extractItem = extractBizModel.getExtractItem(key);
            if (extractItem != null) {
                return extractItem.getKey();
            }
        }
        return null;
    }

    public KVText getKVTextValue(String tableId, String model, String key) {
        ExtractBizModel extractBizModel = getChapterModel(tableId).getModel(model);
        if (extractBizModel != null) {
            ExtractItem extractItem = extractBizModel.getExtractItem(key);
            if (extractItem != null) {
                return extractItem.getValue();
            }
        }
        return null;
    }

    public KVText getKVTextValue(ExtractBizModel extractBizModel, String key) {
        if (extractBizModel != null) {
            ExtractItem extractItem = extractBizModel.getExtractItem(key);
            if (extractItem != null) {
                return extractItem.getValue();
            }
        }
        return null;
    }

    public List<KVText> getKVTextValues(String tableId, String model, String key) {
        ExtractBizModel extractBizModel = getChapterModel(tableId).getModel(model);
        if (extractBizModel != null) {
            ExtractItem extractItem = extractBizModel.getExtractItem(key);
            if (extractItem != null) {
                return extractItem.getValues();
            }
        }
        return null;
    }

    public List<ComponentResult.TextPosition> getContentAndPositionList(KVText value) {
        if (value == null) {
            return new ArrayList();
        }
        return getContentAndPositionList(value.getTextLayoutList());
    }

    public List<ComponentResult.TextPosition> getContentAndPositionList(TextLayout textLayout) {
        List<ComponentResult.TextPosition> contentAndPositionList = new ArrayList();
        if (textLayout==null) {
            return contentAndPositionList;
        }
        ComponentResult.TextPosition contentAndPosition = new ComponentResult().new TextPosition();
        contentAndPosition.setX(textLayout.getLeft());
        contentAndPosition.setY(textLayout.getTop());
        contentAndPosition.setContent(textLayout.getText());
        contentAndPositionList.add(contentAndPosition);
        return contentAndPositionList;
    }

    public List<ComponentResult.TextPosition> getContentAndPositionList(List<TextLayout> textLayoutList) {
        List<ComponentResult.TextPosition> contentAndPositionList = new ArrayList();
        if (CollectionUtils.isEmpty(textLayoutList)) {
            return contentAndPositionList;
        }
        for (TextLayout textLayout : textLayoutList) {
            double x = textLayout.getLeft();
            double y = textLayout.getTop();
            String content = textLayout.getText();
            if (!(x == 0 && y == 0)) {
                ComponentResult.TextPosition contentAndPosition = new ComponentResult().new TextPosition();
                contentAndPosition.setX(x);
                contentAndPosition.setY(y);
                contentAndPosition.setContent(content);
                contentAndPositionList.add(contentAndPosition);
            }
        }
        return contentAndPositionList;
    }

    public List<ContentAndPosition> getContentAndPositionList2(KVText value) {
        if (value == null) {
            return new ArrayList();
        }
        return getContentAndPositionList2(value.getTextLayoutList());
    }

    public List<ContentAndPosition> getContentAndPositionList2(List<TextLayout> textLayoutList) {
        List<ContentAndPosition> contentAndPositionList = new ArrayList();
        if (CollectionUtils.isEmpty(textLayoutList)) {
            return contentAndPositionList;
        }
        for (TextLayout textLayout : textLayoutList) {
            double x = textLayout.getLeft();
            double y = textLayout.getTop();
            String content = textLayout.getText();
            int pageNum = textLayout.getPageNumber();
            if (!(x == 0 && y == 0)) {
                ContentAndPosition contentAndPosition = new ContentAndPosition();
                contentAndPosition.setX(x);
                contentAndPosition.setY(y);
                contentAndPosition.setContent(content);
                contentAndPosition.setPageNum(pageNum);
                contentAndPositionList.add(contentAndPosition);
            }
        }
        return contentAndPositionList;
    }


    public List<IndustryIndicatorList> getIndustryIndicatorList() {
        return industryIndicatorList;
    }

    public void setIndustryIndicatorList(List<IndustryIndicatorList> industryIndicatorList) {
        this.industryIndicatorList = industryIndicatorList;
    }

    public IaadGrade getIaadGrade() {
        return iaadGrade;
    }

    public void setIaadGrade(IaadGrade iaadGrade) {
        this.iaadGrade = iaadGrade;
    }


    /**
     * @auth 佟媛媛
     * @date 18/11/7 下午6:54
     * @desc 获取指标信息
     */
    public IndustryIndicatorList getIndustryIndicatorList(String name) {
        List<IndustryIndicatorList> list = getIndustryIndicatorList();
        for (IndustryIndicatorList item : list) {
            if (name.equals(item.getIndicatorShortName())) {
                item.getIndicatorId();
                return item;
            }
        }
        return null;
    }

    public IaadIndicatorGradeDetail getIaadIndicatorGradeDetail(IndustryIndicatorList indicator,List<ContentAndPosition> textPositionList, String value, String automateScore, String thresholdValue,String thresholdScore, int pageNum, String remark) {
        if (getIaadGrade() == null) {
            return null;
        }
        if(!CollectionUtils.isEmpty(textPositionList)){
            pageNum = textPositionList.get(0).getPageNum();
        }
        IaadIndicatorGradeDetail iaadIndicatorGradeDetail = new IaadIndicatorGradeDetail();
        iaadIndicatorGradeDetail.setIndicatorName(indicator.getIndicatorName());
        iaadIndicatorGradeDetail.setIndicatorGradeId(getIaadGrade().getIndicatorGradeId());
        iaadIndicatorGradeDetail.setIndicatorGradeDetailId(UUID.randomUUID().toString());
        iaadIndicatorGradeDetail.setIndicatorOriginalValue(value);
        iaadIndicatorGradeDetail.setCreateTime(Timestamp.valueOf(LocalDateTime.now()));
        iaadIndicatorGradeDetail.setAutomateScore(automateScore);
        iaadIndicatorGradeDetail.setAdjustmentScore(automateScore);
        iaadIndicatorGradeDetail.setIndicatorId(indicator.getIndicatorId());
        iaadIndicatorGradeDetail.setIndicatorOriginalName(indicator.getIndicatorName());
        iaadIndicatorGradeDetail.setIndicatorProperty(indicator.getIndicatorProperty());
        iaadIndicatorGradeDetail.setThresholdCategory(indicator.getThresholdCategory());
        iaadIndicatorGradeDetail.setIndustryType(indicator.getIndustryType());
        iaadIndicatorGradeDetail.setInputType("02");//1人工 2机器
        iaadIndicatorGradeDetail.setStatus("01");
        iaadIndicatorGradeDetail.setExtractData(remark);
        iaadIndicatorGradeDetail.setThresholdValue(thresholdValue);
        iaadIndicatorGradeDetail.setThresholdScore(thresholdScore);
        iaadIndicatorGradeDetail.setWeight(indicator.getWeight());
        iaadIndicatorGradeDetail.setPageNum(pageNum + "");
        iaadIndicatorGradeDetail.setIndicatorUnit(indicator.getUnitType());
        iaadIndicatorGradeDetail.setXpath(new GsonBuilder().create().toJson(textPositionList));
        return iaadIndicatorGradeDetail;
    }

    public IaadIndicatorGradeDetail getIaadIndicatorGradeDetail(IndustryIndicatorList indicator, String value, String automateScore, String thresholdValue,String thresholdScore, int pageNum, String remark) {
        if (getIaadGrade() == null) {
            return null;
        }
        IaadIndicatorGradeDetail iaadIndicatorGradeDetail = new IaadIndicatorGradeDetail();
        iaadIndicatorGradeDetail.setIndicatorName(indicator.getIndicatorName());
        iaadIndicatorGradeDetail.setIndicatorGradeId(getIaadGrade().getIndicatorGradeId());
        iaadIndicatorGradeDetail.setIndicatorGradeDetailId(UUID.randomUUID().toString());
        iaadIndicatorGradeDetail.setIndicatorOriginalValue(value);
        iaadIndicatorGradeDetail.setCreateTime(Timestamp.valueOf(LocalDateTime.now()));
        iaadIndicatorGradeDetail.setAutomateScore(automateScore);
        iaadIndicatorGradeDetail.setAdjustmentScore(automateScore);
        iaadIndicatorGradeDetail.setIndicatorId(indicator.getIndicatorId());
        iaadIndicatorGradeDetail.setIndicatorOriginalName(indicator.getIndicatorName());
        iaadIndicatorGradeDetail.setIndicatorProperty(indicator.getIndicatorProperty());
        iaadIndicatorGradeDetail.setThresholdCategory(indicator.getThresholdCategory());
        iaadIndicatorGradeDetail.setIndustryType(indicator.getIndustryType());
        iaadIndicatorGradeDetail.setInputType("02");//1人工 2机器
        iaadIndicatorGradeDetail.setStatus("01");
        iaadIndicatorGradeDetail.setExtractData(remark);
        iaadIndicatorGradeDetail.setThresholdValue(thresholdValue);
        iaadIndicatorGradeDetail.setThresholdScore(thresholdScore);
        iaadIndicatorGradeDetail.setWeight(indicator.getWeight());
        iaadIndicatorGradeDetail.setPageNum(pageNum + "");
        iaadIndicatorGradeDetail.setIndicatorUnit(indicator.getUnitType());
        return iaadIndicatorGradeDetail;
    }

    public IaadIndicatorGradeDetail getIaadIndicatorGradeDetail(IndustryIndicatorList indicator, String value, int pageNum, String extractData, String remark) {
        if (indicator == null) {
            return null;
        }
        String unit = getUnit(extractData);
        Map scoreAndThresholdValue = getScoreAndThresholdValue(indicator.getIndicatorId(),indicator.getThresholdCategory(), value, indicator.getUnitType(), unit, indicator.getWeight());
        String thresholdValue = (String) scoreAndThresholdValue.get("thresholdValue");
        String automateScore = (String) scoreAndThresholdValue.get("automateScore");
        String thresholdScore = (String) scoreAndThresholdValue.get("thresholdScore");
        double _value = (double) scoreAndThresholdValue.get("value");
        if (_value != Double.MAX_VALUE) {
            value = _value + "";
        }
        return getIaadIndicatorGradeDetail(indicator, value, automateScore, thresholdValue,thresholdScore, pageNum, remark);
    }

    public IaadIndicatorGradeDetail getIaadIndicatorGradeDetail(IndustryIndicatorList indicator,List<ContentAndPosition> textPositionList, String value, int pageNum, String extractData, String remark) {
        if (indicator == null) {
            return null;
        }
        String unit = getUnit(extractData);
        Map scoreAndThresholdValue = getScoreAndThresholdValue(indicator.getIndicatorId(),indicator.getThresholdCategory(), value, indicator.getUnitType(), unit, indicator.getWeight());
        String thresholdValue = (String) scoreAndThresholdValue.get("thresholdValue");
        String automateScore = (String) scoreAndThresholdValue.get("automateScore");
        String thresholdScore = (String) scoreAndThresholdValue.get("thresholdScore");
        double _value = (double) scoreAndThresholdValue.get("value");
        if (_value != Double.MAX_VALUE) {
            value = _value + "";
        }
        return getIaadIndicatorGradeDetail(indicator,textPositionList, value, automateScore, thresholdValue,thresholdScore, pageNum, remark);
    }

    public IaadIndicatorGradeDetail getIaadIndicatorGradeDetail(IndustryIndicatorList indicator, String value, String unit, int pageNum, String remark) {
        if (indicator == null) {
            return null;
        }
        Map scoreAndThresholdValue = getScoreAndThresholdValue(indicator.getIndicatorId(),indicator.getThresholdCategory(), value, indicator.getUnitType(), unit, indicator.getWeight());
        String thresholdValue = (String) scoreAndThresholdValue.get("thresholdValue");
        String automateScore = (String) scoreAndThresholdValue.get("automateScore");
        String thresholdScore = (String) scoreAndThresholdValue.get("thresholdScore");
        double _value = (double) scoreAndThresholdValue.get("value");
        if (_value != Double.MAX_VALUE) {
            value = _value + "";
        }
        return getIaadIndicatorGradeDetail(indicator, value, automateScore, thresholdValue,thresholdScore, pageNum, remark);
    }

    public IaadIndicatorGradeDetail getIaadIndicatorGradeDetail(IndustryIndicatorList indicator,List<ContentAndPosition> textPositionList, String value, String unit, int pageNum, String remark) {
        if (indicator == null) {
            return null;
        }
        Map scoreAndThresholdValue = getScoreAndThresholdValue(indicator.getIndicatorId(),indicator.getThresholdCategory(), value, indicator.getUnitType(), unit, indicator.getWeight());
        String thresholdValue = (String) scoreAndThresholdValue.get("thresholdValue");
        String automateScore = (String) scoreAndThresholdValue.get("automateScore");
        String thresholdScore = (String) scoreAndThresholdValue.get("thresholdScore");
        double _value = (double) scoreAndThresholdValue.get("value");
        if (_value != Double.MAX_VALUE) {
            value = _value + "";
        }
        return getIaadIndicatorGradeDetail(indicator,textPositionList, value, automateScore, thresholdValue,thresholdScore, pageNum, remark);
    }

    public Map getScoreAndThresholdValue(String indicatorId,String thresholdCategory, String indicatorValue, String standardUnit, String actualUnit, String weight) {
        indicatorValue = indicatorValue.replace(",", "").trim().replace(" ", "");
        Map rs = new HashMap();
        //计算得分和阈值
        double automateScore = 0;//得分 = 阈值对应分数 * 权重
        String score = null;
        String thresholdValue = "未匹配到阈值";
        String thresholdScore = null;
        double value = Double.MAX_VALUE;
        rs.put("automateScore", automateScore + "");
        rs.put("thresholdValue", thresholdValue);
        rs.put("thresholdScore", thresholdScore);
        rs.put("value", value);
        try {
            List<IndustryIndicatorThreshold> industryIndicatorThresholdList = getIndustryIndicatorThresholdList(indicatorId);
            if (industryIndicatorThresholdList == null) return rs;
            //文本类型判断
            if("01".equals(thresholdCategory)){//文本
                for (IndustryIndicatorThreshold threshold : industryIndicatorThresholdList) {
                    if(indicatorValue.contains(threshold.getConditions()) || threshold.getConditions().contains(indicatorValue)){
                        score = threshold.getScore();
                        thresholdValue = threshold.getConditions();
                        thresholdScore = threshold.getScore();
                        break;
                    }
                }
            }else if("02".equals(thresholdCategory)){//数值
                //数字类型判断
                value = getActualValue(indicatorValue, standardUnit, actualUnit);
                for (IndustryIndicatorThreshold threshold : industryIndicatorThresholdList) {
                    Map s = getScoreAndThresholdValue(threshold, value);
                    score = (String) s.get("score");
                    thresholdValue = (String) s.get("thresholdValue");
                    thresholdScore = threshold.getScore();
                    if (StringUtils.isNotEmpty(score)) {
                        break;
                    }
                }
            }
            if (StringUtils.isNotEmpty(score) && StringUtils.isNotEmpty(weight)) {
                automateScore = Double.valueOf(score) * Double.valueOf(weight);
                automateScore = getTwoDecimal(automateScore);
            }
            rs.put("automateScore", automateScore + "");
            rs.put("thresholdValue", thresholdValue);
            rs.put("thresholdScore", thresholdScore);
            rs.put("value", value);
            return rs;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return rs;
        }
    }

    private double getActualValue(String indicatorValue, String standardUnit, String actualUnit) {
        double value = Double.MAX_VALUE;
        try {
            value = StringUtils.isNotEmpty(indicatorValue) && isNum(indicatorValue) ? Double.valueOf(indicatorValue) : Double.MAX_VALUE;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
//                 单位换算
        if (value != Double.MAX_VALUE) {
            if (StringUtils.isEmpty(actualUnit)) {
                return value;
            }  else if (StringUtils.isNotEmpty(actualUnit) && actualUnit.equals(standardUnit) && !"%".equals(actualUnit)) {
                return value;
            } else if ("%".equals(actualUnit)) {
                return getTwoDecimal(value * 100);
            }else {
                double v = getActualValue(standardUnit, actualUnit, value);
                //TODO 若单位未匹配则利用原值
                if (v == Double.MAX_VALUE) {
                    return value;
                } else {
                    return v;
                }
            }
        }
        return value;
    }

    private List<IndustryIndicatorThreshold> getIndustryIndicatorThresholdList(String indicatorId) {
        List<IndustryIndicatorList> list = getIndustryIndicatorList();
        for (IndustryIndicatorList item : list) {
            if (indicatorId.equals(item.getIndicatorId())) {
                return item.getThresholdList();
            }
        }
        return new ArrayList<>();
    }

    private Map getScoreAndThresholdValue(IndustryIndicatorThreshold threshold, double indicatorValue) {
        Map rs = new HashMap();
        String score = null;
        String thresholdValue = "未匹配到阈值";
        //转换为数字进行比较
        if (isRange(threshold.getConditions()) && indicatorValue != Double.MAX_VALUE) {
            String condition = threshold.getConditions().replace(" ", "");
            String[] conditions = condition.substring(1, condition.length() - 1).split(",");
            boolean left = condition.split(",")[0].contains("(") ? false : true;
            boolean right = condition.split(",")[1].contains(")") ? false : true;
            double start = conditions[0].contains("-∞") ? -Double.MAX_VALUE : Double.valueOf(conditions[0]);
            double end = conditions[1].contains("+∞") ? Double.MAX_VALUE : Double.valueOf(conditions[1]);
            if (indicatorValue != Double.MAX_VALUE && (left ? indicatorValue >= start : indicatorValue > start) && (right ? indicatorValue <= end : indicatorValue < end)) {
                score = threshold.getScore();
                thresholdValue = threshold.getConditions();
            }
        }
        rs.put("score", score);
        rs.put("thresholdValue", thresholdValue);
        return rs;
    }


    /**
     * @auth 佟媛媛
     * @date 18/10/26 上午11:39
     * @desc 将数据整理成一行
     */
    public JsonObject returnOne(JsonArray data) {
        JsonObject jsonObject = new JsonObject();
        StringBuilder text = new StringBuilder();
        double left = 0;
        double top = 0;
        if (data != null) {
            for (JsonElement element : data) {
                JsonObject _data = element.getAsJsonObject();
                double _left = _data.get("left").getAsDouble();
                double _top = _data.get("top").getAsDouble();
                if (_top != 0 && _left != 0) {
                    top = _top;
                    left = _left;
                    break;
                }
            }
            for (JsonElement element : data) {
                JsonObject _data = element.getAsJsonObject();
                String _text = _data.get("text").getAsString();
                text.append(_text);
            }
        }
        jsonObject.addProperty("text", text.toString());
        jsonObject.addProperty("left", left);
        jsonObject.addProperty("top", top);
        return jsonObject;
    }

    /**
     * @auth 佟媛媛
     * @date 18/10/26 上午11:39
     * @desc 将数据整理成一行 去除表格行
     */
    public JsonObject returnOneExpectTable(JsonArray data,PageModel pageModel) {
        JsonObject jsonObject = new JsonObject();
        StringBuilder text = new StringBuilder();
        double left = 0;
        double top = 0;
        if (data != null) {
            if(isInTable(data.get(0).getAsJsonObject(),pageModel)){
                jsonObject.addProperty("text", text.toString());
                jsonObject.addProperty("left", left);
                jsonObject.addProperty("top", top);
                return jsonObject;
            }
            for (JsonElement element : data) {
                JsonObject _data = element.getAsJsonObject();
                double _left = _data.get("left").getAsDouble();
                double _top = _data.get("top").getAsDouble();
                if (_top != 0 && _left != 0) {
                    top = _top;
                    left = _left;
                    break;
                }
            }
            for (JsonElement element : data) {
                JsonObject _data = element.getAsJsonObject();
                String _text = _data.get("text").getAsString();
                text.append(_text);
            }
        }
        jsonObject.addProperty("text", text.toString());
        jsonObject.addProperty("left", left);
        jsonObject.addProperty("top", top);
        return jsonObject;
    }


    /**
     * @auth 佟媛媛
     * @date 18/12/3 下午5:21
     * @desc 将数据整理成一行 且 返回匹配文本的坐标
     */
    public JsonObject returnOne(JsonArray data, String keyword) {
        JsonObject jsonObject = new JsonObject();
        StringBuilder text = new StringBuilder();
        double left = 0;
        double top = 0;
        if (data != null) {
            for (JsonElement element : data) {
                JsonObject _data = element.getAsJsonObject();
                String _text = _data.get("text").getAsString();
                text.append(_text);
            }
            JsonObject object = getLeftAndTop(data,text.toString(),keyword);
            left = object.get("left").getAsDouble();
            top = object.get("top").getAsDouble();
        }
        jsonObject.addProperty("text", text.toString());
        jsonObject.addProperty("left", left);
        jsonObject.addProperty("top", top);
        return jsonObject;
    }


    public JsonObject getLeftAndTop(JsonArray data,String content,String keyword){
        JsonObject jsonObject = new JsonObject();
        double left = 0;
        double top = 0;
        int index = stringFilter(content).indexOf(stringFilter(keyword));
        if(data!=null && index!=-1){
            if(data.size()>1){
                List<Map> list = new ArrayList<>();
                for (JsonElement element : data) {
                    Map map = new HashMap();
                    JsonObject _data = element.getAsJsonObject();
                    double _left = _data.get("left").getAsDouble();
                    double _top = _data.get("top").getAsDouble();
                    String _text = stringFilter(_data.get("text").getAsString());
                    int _index = stringFilter(content).indexOf(_text)+_text.length();
                    if(_left!=0 && _top!=0 && StringUtils.isNotEmpty(_text)){
                        map.put("left",_left);
                        map.put("top",_top);
                        map.put("text",_text);
                        map.put("index",_index);
                        list.add(map);
                    }
                }
                for(int i=0;i<list.size();i++){
                   int _index = (int)list.get(i).get("index");
                   if(index < _index){
                       left = (double)list.get(i).get("left");
                       top = (double)list.get(i).get("top");
                       break;
                   }else if(index == _index && i<list.size()-1){
                       left = (double)list.get(i+1).get("left");
                       top = (double)list.get(i+1).get("top");
                       break;
                   }
                }
            }else{
                left = data.get(0).getAsJsonObject().get("left").getAsDouble();
                top = data.get(0).getAsJsonObject().get("top").getAsDouble();
            }
        }
        jsonObject.addProperty("left", left);
        jsonObject.addProperty("top", top);
        return jsonObject;
    }

    public String getPromptMsg() {
        return promptMsg;
    }

    public void setPromptMsg(String promptMsg) {
        this.promptMsg = promptMsg;
    }


    protected boolean isInTable(JsonObject jsonObject, PageModel pageModel) {
        List<TableArea> tableAreaList = recognizePageTableRegion(pageModel);
        if (CollectionUtils.isEmpty(tableAreaList)) {
            return false;
        }
        double height = jsonObject.get("height").getAsDouble();
        double top = jsonObject.get("top").getAsDouble();
        double left = jsonObject.get("left").getAsDouble();
        if (top == 0 && left == 0) {
            return false;
        }
        boolean isInner = false;
        for (int i = 0; i < tableAreaList.size(); i++) {
            TableArea tableArea = tableAreaList.get(i);
            if (top > tableArea.getTop() && (top + height) < (tableArea.getTop() + tableArea.getHeight())) {
                isInner = true;
                break;
            }
        }
        return isInner;
    }

    private List<String> commandLine(String[] args) throws Exception {
        CommandLineParser parser = new DefaultParser();
        CommandLine cmd = parser.parse(PdfExtractor.buildOptions(), args);
        return new PdfExtractor(cmd).extractTables(cmd);
    }

    private List<String> extractPdfByTable(String[] args) throws Exception {
        return commandLine(args);
    }


    private List<TableArea> recognizePageTableRegion(PageModel pageModel) {
        List<TableArea> tableAreaList = new ArrayList<>();
        try {
            List<String> pageTableDataList = pageModel.getTableDataList();
            if (CollectionUtils.isEmpty(pageTableDataList)) {
                return null;
            }
            for (int i = 0; i < pageTableDataList.size(); i++) {
                String tableJsonData = pageTableDataList.get(i);
                JsonArray tableDataArray = str2Json(tableJsonData).getAsJsonArray();
                JsonObject tableData = tableDataArray.get(0).getAsJsonObject();
                double top = tableData.get("top").getAsDouble();
                double left = tableData.get("left").getAsDouble();
                double width = tableData.get("width").getAsDouble();
                double height = tableData.get("height").getAsDouble();
                TableArea tableArea = new TableArea(pageModel.getPageNumber(), top, left, width, height);
                tableAreaList.add(tableArea);
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return tableAreaList;
    }


    private JsonElement str2Json(String jsonString) {
        return GsonUtil.getInstance().parse(jsonString);
    }


    public JsonObject getLastLine(PageModel pageModel){
        JsonArray jsonTextDataArray = pageModel.getJsonTextData()!=null?pageModel.getJsonTextData().getAsJsonArray():null;
        if(jsonTextDataArray!=null){
            for(JsonElement element : jsonTextDataArray){
                JsonArray data = element.getAsJsonObject()!=null?element.getAsJsonObject().getAsJsonArray("data"):null;//当页文本
                if(data!=null && data.size()>0){
                   return returnOne(data.get(data.size()-1).getAsJsonArray());
                }
            }
        }
        return null;
    }

    public JsonObject getFirstLine(PageModel pageModel){
        JsonArray jsonTextDataArray = pageModel.getJsonTextData()!=null?pageModel.getJsonTextData().getAsJsonArray():null;
        if(jsonTextDataArray!=null){
            for(JsonElement element : jsonTextDataArray){
                JsonArray data = element.getAsJsonObject()!=null?element.getAsJsonObject().getAsJsonArray("data"):null;//当页文本
                if(data!=null && data.size()>0){
                    return returnOne(data.get(0).getAsJsonArray());
                }
            }
        }
        return null;
    }
}
